package gw.com.android.ui.trade;

import android.text.TextUtils;

import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import gw.com.android.app.AppMain;
import gw.com.android.app.GTConfig;
import gw.com.android.ui.quote2.QuoteChartConfig;
import gw.com.android.utils.IOUtils;
import gw.com.android.utils.ThreadPool;

/**
 * 推荐手数
 *
 * @author jett
 * @since 2018-04-20.
 */
public class OrderLotHelper {

    static void saveLot(final int code, final String lot) {
        ThreadPool.getInstance().execute(new Runnable() {
            @Override
            public void run() {
                saveProductLot(code, lot);
            }
        });
    }

    private static void saveProductLot(int code, String lot) {
        List<String> localLots = getLocalLots(code);
        if (localLots == null) {
            localLots = new ArrayList<>();
        }
        // 本地只保存30条数据
        while (localLots.size() > 30) {
            localLots.remove(0);
        }
        localLots.add(lot);
        StringBuilder sb = new StringBuilder();
        for (String str : localLots) {
            if (!TextUtils.isEmpty(str)) {
                sb.append(str).append(",");
            }
        }
        sb.deleteCharAt(sb.length() - 1);
        File file = getLotFile(code);
        IOUtils.writeFile(file, sb.toString(), false);
    }

    static List<String> getRecommendLots(int code, float maxLot) {
        List<String> lots = getLocalLots(code);
        // 将本地数据，转化成  LotData 对象
        List<LotData> datas = buildLotDatas(lots);
        if (datas == null || datas.isEmpty()) {
            return getDefaultLots(code);
        }
        //  排序，次数大的靠前，次数相同的，手数大的靠前
        sortByCount(datas);
        //  拿到操作频率最高的手数
        List<Float> result = new ArrayList<>();
        LotData firstData = datas.get(0);
        result.add(firstData.lot);
        //  根据第一手数，生成第三个手数
        float thirdLot = calcThirdLot(firstData.lot, maxLot);

        datas.remove(firstData);
        if (datas.isEmpty()) {
            return calcQuickLot(code, result, thirdLot, maxLot);
        }
        //  排序，手数大的靠前，手数相同的，次数大的靠前
        sortByLot(datas);
        boolean hasSecond = false;
        for (LotData data : datas) {
            if (data.lot != thirdLot) {
                result.add(data.lot);
                hasSecond = true;
                break;
            }
        }
        if (!hasSecond) {
            return calcQuickLot(code, result, thirdLot, maxLot);
        }

        // 取最近的一笔交易手数，为第四个手数
        float fourthLot = 0;
        for (int i = lots.size() - 1; i >= 0; i--) {
            String strLot = lots.get(i);
            Float fLot = Float.valueOf(strLot);
            if (!result.contains(fLot) && fLot != thirdLot) {
                fourthLot = fLot;
                break;
            }
        }
        if (fourthLot <= 0) {
            // 如果第四个手数取不到，第五个手数，就更不要去想啦！哈哈哒
            return calcQuickLot(code, result, thirdLot, maxLot);
        }
        result.add(fourthLot);

        // 再次取最近的一笔交易手数的最小值为 ，第五手数
        for (int i = lots.size() - 1; i >= 0; i--) {
            String strLot = lots.get(i);
            Float fLot = Float.valueOf(strLot);
            if (!result.contains(fLot) && fLot != thirdLot) {
                result.add(fLot);
            }
        }
        /*if (lots.size() <= 3) {
            return calcQuickLot(result, thirdLot);
        }
        float last1 = Float.valueOf(lots.get(lots.size() - 1));
        float last2 = Float.valueOf(lots.get(lots.size() - 2));
        float last3 = Float.valueOf(lots.get(lots.size() - 3));
        float[] lasts = {last1, last2, last3};
        Arrays.sort(lasts);
        for (float last : lasts) {
            if (!result.contains(last)) {
                result.add(last);
                return calcQuickLot(result, thirdLot);
            }
        }
        // 最近三笔交易取到的手数，都是已经重复的手数时 ，再次取出最新一笔交易手数 ，为第五手数
        lots = lots.subList(0, lots.size() - 3);
        for (int i = lots.size() - 1; i >= 0; i--) {
            String strLot = lots.get(i);
            Float fLot = Float.valueOf(strLot);
            if (!result.contains(fLot)) {
                result.add(fLot);
            }
        }*/
        // 本地手数不足时，根据第三手数，计算其它对应的手数
        return calcQuickLot(code, result, thirdLot, maxLot);
    }

    /**
     * 手数转化成 LotData对象
     */
    private static List<LotData> buildLotDatas(List<String> lots) {
        if (lots == null || lots.isEmpty()) {
            return null;
        }
        HashMap<Float, LotData> map = new HashMap<>();
        for (int i = 0; i < lots.size(); i++) {
            float lot = Float.valueOf(lots.get(i));

            LotData data = map.get(lot);
            if (data == null) {
                data = new LotData(lot, 1);
            } else {
                data.count++;
            }
            map.put(lot, data);
        }
        List<LotData> datas = new ArrayList<>();
        for (Map.Entry<Float, LotData> me : map.entrySet()) {
            LotData value = me.getValue();
            datas.add(value);
        }
        return datas;
    }

    /**
     * 排序，计算出最大的手数，为第二个手数
     */
    private static void sortByLot(List<LotData> datas) {
        Collections.sort(datas, new Comparator<LotData>() {
            @Override
            public int compare(LotData d1, LotData d2) {
                if (d2.lot > d1.lot) {
                    return 1;
                }
                if (d2.lot < d1.lot) {
                    return -1;
                }
                return d2.count - d1.count;
            }
        });
    }

    /**
     * 排序，计算出使用频率最高的手数为第一手数
     */
    private static void sortByCount(List<LotData> datas) {
        Collections.sort(datas, new Comparator<LotData>() {
            @Override
            public int compare(LotData d1, LotData d2) {
                int result = d2.count - d1.count;
                if (result == 0) {
                    if (d2.lot > d1.lot) {
                        return 1;
                    }
                    if (d1.lot > d2.lot) {
                        return -1;
                    }
                    return 0;
                }
                return result;
            }
        });
    }

    private static String formatLot(float lot) {
        return String.format(Locale.getDefault(), "%.2f", lot);
    }

    /**
     * 第三个手数：根据第一手数，取大于第一手数的整数，以 .5结尾，如 ： 0.50，1.00，1.50，2.00，2.50
     */
    private static Float calcThirdLot(float firstLot, float maxLot) {
        if (firstLot >= maxLot) {
            return maxLot - 0.5F;
        }
        float ceil = (float) Math.ceil(firstLot);
        if (ceil == firstLot) {
            return ceil + 0.5F;
        }
        float f = ceil - 0.5F;
        if (firstLot < f) {
            return f;
        }
        return ceil;
    }

    /**
     * 本地手数不足时，根据第三手数，生成其余的手数
     */
    private static List<String> calcQuickLot(int code, List<Float> list, float thirdLot, float maxLot) {
        if (list == null || list.isEmpty()) {
            return getDefaultLots(code);
        }
        int remain = 4 - list.size();
        boolean plus = thirdLot < maxLot; // 推荐手数，小于产品可下单的最大手数时，其余推荐手数往上加，否则减
        float mLot;
        if (plus) {
            mLot = thirdLot + 0.5F;
        } else {
            mLot = thirdLot - 0.5F;
        }
        for (int i = 0; i < remain; i++) {
            while (list.contains(mLot) || mLot == thirdLot) {
                if (plus && mLot < maxLot) {
                    mLot += 0.5F;
                } else {
                    plus = false;
                    mLot -= 0.5F;
                }
            }
            list.add(mLot);
        }
        // 插入第三手数，并将手数转化成String返回
        list.add(2, thirdLot);
        List<String> result = new ArrayList<>();
        for (float value : list) {
            result.add(formatLot(value));
        }
        return result;
    }

    /**
     * 获取本地保存的手数，格式为：eg: 0.01,0.5,0.78,1.2
     */
    private static List<String> getLocalLots(int code) {
        File file = getLotFile(code);
        String value = IOUtils.readFile(file);
        if (TextUtils.isEmpty(value)) {
            return null;
        }
        String[] split = value.split(",");
        if (split.length <= 0) {
            return null;
        }
        List<String> lots = new ArrayList<>();
        for (String str : split) {
            if (!TextUtils.isEmpty(str)) {
                lots.add(str);
            }
        }
        return lots;
    }

    private static File getLotFile(int code) {
        File dir = new File(AppMain.getApp().getFilesDir(), "recommend_lot");
        String mCurName = GTConfig.instance().mCurName;
        if (TextUtils.isEmpty(mCurName)) {
            mCurName = "guest";
        }
        dir = new File(dir, mCurName);
        return new File(dir, String.valueOf(code));
    }

    /**
     * 本地无数据时，默认的手数
     */
    private static List<String> getDefaultLots(int code) {
        List<String> lots = new ArrayList<>();
        if (code == QuoteChartConfig.LIAN_GOLD || code == QuoteChartConfig.LIAN_SILVER) {
            lots.add("0.10");
            lots.add("0.50");
            lots.add("1.00");
            lots.add("1.50");
            lots.add("2.00");
        } else {
            lots.add("0.01");
            lots.add("0.10");
            lots.add("0.50");
            lots.add("1.00");
            lots.add("2.00");
        }
        return lots;
    }

    private static class LotData {
        float lot;
        int count;

        LotData(float lot, int count) {
            this.lot = lot;
            this.count = count;
        }
    }

}
